<?php
declare(strict_types=1);

namespace app\common\business;

use app\common\model\mysql\Goods as GoodsModel;
use think\Exception;
use think\facade\Log;

class Goods extends BusiBase
{
    public function __construct()
    {
        $this->model = new GoodsModel();
    }

    /**
     * 获取分页数据
     *
     * @param array $data
     * @param int $number
     * @return array
     */
    public function getLists(array $data, int $number = 10)
    {
        $searchKey = [];
        if ($data) $searchKey = array_keys($data);

        try{
            $list = $this->model->getLists($searchKey, $data, $number);
        } catch (\Exception $e) {
            Log::error(get_class($this)." find data error: ".$e->getMessage());
            return $this->returnNullDataArray($number);
        }
        return $list->toArray();
    }

    /**
     * 商品添加
     *
     * @param array $data
     * @return bool
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function add(array $data)
    {
        // 查找当前分类中是否存在该商品名称
        $where = ['title' => $data['title'], 'category_id' => $data['category_id']];
        $find  = $this->model->where($where)->find();
        if ($find) throw new Exception('该名称已存在');

        // 开启事务
        $this->model->startTrans();
        try{
            // 商品添加
            $addId = $this->insert($data);

            // 无规格属性时默认为当前数据
            if ($data['goods_specs_type'] == 1) {
                $data['skus'][] = [
                    'propvalnames' => [
                        'propvalids' => 0,
                        'skuSellPrice' => $data['price'],
                        'skuMarketPrice' => $data['cost_price'],
                        'skuStock' => $data['stock']
                    ]
                ];
            }

            $goodsSku = new GoodsSku();
            $data['goods_id'] = $addId;
            $res      = $goodsSku->saveAll($data);
            if (!empty($res)) {
                $stock = array_sum(array_column($res, 'stock'));
                $updateData = [
                    'price'      => $res[0]['price'],
                    'cost_price' => $res[0]['cost_price'],
                    'stock'      => $stock,
                    'sku_id'     => $res[0]['id']
                ];

                $this->edit(intval($addId), $updateData);
            }
            // 事务提交
            $this->model->commit();
        } catch (\think\Exception $e) {
            // 事务回滚
            $this->model->rollback();
            throw new Exception($e->getMessage());
        }
        return true;
    }

    /**
     * 商品是否首页推荐修改
     *
     * @param int $id
     * @param int $is_index_recommend
     * @return mixed
     * @throws Exception
     */
    public function updateIsIndexRecommentById(int $id, int $is_index_recommend)
    {
        // 检查该数据是否存在
        $data = $this->checkDataById($id);
        if (empty($data['big_image'])) throw new Exception('该商品无法首页推荐');
        if ($data['is_index_recommend'] == $is_index_recommend) throw new Exception('首页推荐无需修改');

        $res  = $this->edit($id, ['is_index_recommend' => $is_index_recommend]);
        return $res;
    }

    /**
     * 获取首页推荐商品
     *
     * @return array
     */
    public function getRotationChart()
    {
        $where = ['is_index_recommend' => 1];
        $field = 'sku_id as id, title, big_image as image';
        try{
            $result = $this->model->getNormalGoodsByCondition($where, $field);
        } catch (\Exception $e) {
            Log::error(get_class($this)." find is_index_recommend error: ".$e->getMessage());
            return [];
        }
        return $result->toArray();
    }

    /**
     * 获取首页栏目推荐商品（首页）
     *
     * @param array $categoryIds
     * @return array
     */
    public function categoryGoodsRecommend(array $categoryIds = [])
    {
        if (!$categoryIds) return [];

        $result = [];
        $category = new Category();
        foreach ($categoryIds as $key=>$cid) {
            $result[$key]['categorys'] = $category->getById($cid, 'id as category_id, name');
            $result[$key]['categorys']['list'] = $category->getNormalByPid($cid, 'id as category_id, name');
            $result[$key]['goods'] = $this->getNormalGoodsFindInSetCategoryId($cid);
        }
        return $result;
    }

    /**
     * 获取对应栏目商品（首页)
     *
     * @param int $categoryId
     * @return array
     */
    public function getNormalGoodsFindInSetCategoryId(int $categoryId)
    {
        $field = 'sku_id as id, title, price, recommend_image as image';
        try{
            $result = $this->model->getNormalGoodsFindInSetCategoryId($categoryId, $field);
        } catch (\Exception $e) {
            Log::error(get_class($this)." find goods where category_path_id has $categoryId error:".$e->getMessage());
            return [];
        }
        return $result->toArray();
    }

    /**
     * 获取栏目对应商品（列表页）
     *
     * @param array $data
     * @param int $number
     * @param array|string[] $order
     * @return array
     */
    public function getNormalLists(array $data, int $number = 5, array $order = ['listorder' => 'desc'])
    {
        $field = "sku_id as id, title, recommend_image as image, price";
        try {
            $lists = $this->model->getNormalLists($data, $number, $field, $order);
            $res   = $lists->toArray();
            $result = [
                'total_page_num' => $res['last_page'] ?? 0,
                'count'          => $res['total'] ?? 0,
                'page'           => $res['current_page'] ?? 0,
                'page_size'      => $number,
                'list'           => $res['data'] ?? []
            ];
        } catch (\Exception $e) {
            Log::error(get_class($this)." getNormalLists error: ".$e->getMessage());
            return $this->returnNullListGoodsArray($number);
        }
        return $result;
    }

    /**
     * 获取商品详情页内容
     *
     * @param int $skuId
     * @return array
     */
    public function getGoodsDetailBySkuId(int $skuId)
    {
        // 根据 skuId 获取当前商品的 sku 及 商品信息
        $goodsSku = new GoodsSku();
        $result   = $goodsSku->getNormalSkuAndGoods($skuId);
        // 判断商品信息是否存在
        if (!$result || !isset($result['goods'])) return [];
        // 提取商品信息
        $goods    = $result['goods'];
        // 获取当前商品的 sku 数据
        $skus     = $goodsSku->getNormalSkuByGoodsId(intval($goods['id']));
        // 生成规格属性数组
        $skuIdArr = array_column($skus, 'id', 'specs_value_ids');

        $skuArr = [];
        if ($goods['goods_specs_type'] == 2) {
            // 获取商品 sku 信息数组
            $specsValue = new SpecsValue();
            $skuArr   = $specsValue->getSpecsValueBySpecsPathIds($skuIdArr, explode(',', (string) $result['specs_value_ids']));
        }

        return [
            'title' => $goods['title'],
            'price' => $result['price'],
            'cost_price' => $result['cost_price'],
            'sales_count' => $goods['sales_count'],
            'stock'       => $result['stock'],
            'gids'        => $skuIdArr,
            'image'       => $goods['carousel_image'],
            'sku'         => $skuArr,
            'detail'      => [
                'd1' => [
                    '商品编号' => $result['id'],
                    '上架时间' => $goods['create_time'],
                    '商品毛重' => '',
                    '商品库存' => $goods['stock']
                ],
                'd2' => preg_replace('/(<img.*?src=")(.*?)/', '$1'.request()->domain()."$2", $goods['description'])
            ]
        ];
    }

    public function updateMoreStock(array $data)
    {
        // 提取待修改数据 id
        $ids      = array_keys($data);
        try {
            // 查找待修改数据
            $skuRes   = $this->model->getNormalByIdArr($ids, 'id,stock');
        } catch (\Exception $e) {
            $this->errorLog('get normal by idarr error: '.$e->getMessage());
            throw new Exception('服务器内部错误');
        }
        if (!$skuRes) return false;
        $skuResult = $skuRes->toArray();
        // 查找待修改数据
        $skuData  = array_column($skuResult, 'stock', 'id');
        // 组装待修改数据数组
        $update   = [];
        foreach ($data as $key=>$val) {
            $update[] = [
                'id' => $key,
                'stock' => $skuData[$key] - $val
            ];
        }
        try {
            $editAll = $this->model->saveAll($update);
        } catch (\Exception $e) {
            $this->errorLog('edit '.json_encode($update).' error: '.$e->getMessage());
            throw new Exception('服务器内部错误');
        }
        return $editAll;
    }
}